package com.idp.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.idp.common.enums.MessageEnum;
import com.idp.common.error.SystemException;
import com.idp.common.model.PageModel;
import com.idp.system.dto.SysDictionaryDto;
import com.idp.system.dto.SysDictionarySearchDto;
import com.idp.system.entity.SysDictionaryEntity;
import com.idp.system.mapper.SysDictionaryMapper;
import com.idp.system.service.SysDictionaryService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 数据字典Service实现类
 *
 * @author King
 */
@Service
public class SysDictionaryServiceImpl implements SysDictionaryService {

    @Autowired
    private SysDictionaryMapper sysDictionaryMapper;

    @Override
    public PageModel<SysDictionaryDto> findByPage(SysDictionarySearchDto sysDictionarySearchDto) {

        PageModel<SysDictionaryDto> page = new PageModel<SysDictionaryDto>();

        List<SysDictionaryDto> list = sysDictionaryMapper.getList(sysDictionarySearchDto);
        page.setList(list);

        return page;
    }

    @Override
    public SysDictionaryDto getById(String id) {

        SysDictionaryDto sysDictionaryDto = sysDictionaryMapper.getById(id);

        if (sysDictionaryDto == null) {

            throw new SystemException(MessageEnum.DATA_NOT_EXIST);
        }
        return sysDictionaryDto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(SysDictionaryDto sysDictionaryDto) {

        checkCode(sysDictionaryDto.getDictCode(), null);

        List<SysDictionaryDto> childList = sysDictionaryDto.getChildList();

        SysDictionaryEntity sysDictionaryEntity = new SysDictionaryEntity();
        BeanUtil.copyProperties(sysDictionaryDto, sysDictionaryEntity);
        sysDictionaryEntity.setId(IdUtil.simpleUUID());
        sysDictionaryEntity.setGroupId("0");
        sysDictionaryMapper.insert(sysDictionaryEntity);

        if (CollectionUtils.isNotEmpty(childList)) {
            for (SysDictionaryDto child : childList) {
                SysDictionaryEntity childEntity = new SysDictionaryEntity();
                BeanUtil.copyProperties(child, childEntity);
                childEntity.setGroupId(sysDictionaryEntity.getId());
                sysDictionaryMapper.insert(childEntity);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(SysDictionaryDto sysDictionaryDto) {

        checkCode(sysDictionaryDto.getDictCode(), null);

        SysDictionaryEntity sysDictionaryEntity = new SysDictionaryEntity();
        BeanUtil.copyProperties(sysDictionaryDto, sysDictionaryEntity);
        sysDictionaryEntity.setId(IdUtil.simpleUUID());
        sysDictionaryMapper.insert(sysDictionaryEntity);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysDictionaryDto sysDictionaryDto) {

        checkCode(sysDictionaryDto.getDictCode(), sysDictionaryDto.getId());

        SysDictionaryEntity dictionary = sysDictionaryMapper.selectById(sysDictionaryDto.getId());

        if (dictionary == null) {
            throw new SystemException(MessageEnum.DATA_NOT_EXIST);
        }

        BeanUtil.copyProperties(sysDictionaryDto, dictionary);
        sysDictionaryMapper.updateById(dictionary);

        List<SysDictionaryDto> childList = sysDictionaryDto.getChildList();

        if (CollectionUtils.isNotEmpty(childList)) {

            LambdaQueryWrapper<SysDictionaryEntity> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysDictionaryEntity::getGroupId, sysDictionaryDto.getId());
            sysDictionaryMapper.delete(queryWrapper);

            for (SysDictionaryDto child : childList) {

                SysDictionaryEntity childEntity = BeanUtil.toBean(child, SysDictionaryEntity.class);
                childEntity.setGroupId(sysDictionaryDto.getId());
                sysDictionaryMapper.insert(childEntity);
            }
        }
    }

    private void checkCode(String dictCode, String id) {

        LambdaQueryWrapper<SysDictionaryEntity> query = new LambdaQueryWrapper<SysDictionaryEntity>();
        query.eq(SysDictionaryEntity::getDictCode, dictCode);
        query.eq(SysDictionaryEntity::getGroupId, "0");
        if (StrUtil.isNotEmpty(id)) {
            query.ne(SysDictionaryEntity::getId, id);
        }
        List<SysDictionaryEntity> list = sysDictionaryMapper.selectList(query);

        if (CollectionUtils.isNotEmpty(list)) {
            throw new SystemException("编码" + dictCode + "已存在");
        }
    }

    @Override
//    @Cacheable(cacheNames = "dictionaryCache", key = "'dictCode'+#code")
    public List<SysDictionaryDto> selectDictionaryByCode(String code) {

        return sysDictionaryMapper.selectDictionaryByCode(code);
    }

    @Override
    public List<SysDictionaryDto> findAll() {

        LambdaQueryWrapper<SysDictionaryEntity> query = new LambdaQueryWrapper<SysDictionaryEntity>();
        query.eq(SysDictionaryEntity::getGroupId, "0");

        List<SysDictionaryEntity> list = sysDictionaryMapper.selectList(query);

        return BeanUtil.copyToList(list, SysDictionaryDto.class);
    }

    @Override
    public void delete(String id) {
        LambdaQueryWrapper<SysDictionaryEntity> query = new LambdaQueryWrapper<SysDictionaryEntity>();
        query.eq(SysDictionaryEntity::getGroupId, id);
        List<SysDictionaryEntity> list = sysDictionaryMapper.selectList(query);
        list.stream().forEach(e -> {
            sysDictionaryMapper.deleteById(e.getId());
        });
        sysDictionaryMapper.deleteById(id);
    }
}
